package ru.compft.common.dao.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import ru.compft.common.dao.TermDao;
import ru.compft.common.data.Term;
import ru.compft.common.utils.CommonUtils;
import ru.compft.common.utils.GlobalConstants;
import ru.compft.common.utils.StringConverter;

import java.io.*;
import java.util.LinkedList;
import java.util.List;

/**
 * User: ASUS
 * Date: 30.07.12
 * Time: 23:15
 * <p/>
 * Пример реализации функциональности работы с терминами
 * Нужен для демонстрационной версии
 */
public class ExampleTermDaoImpl implements TermDao {
    private static final Logger logger = LoggerFactory.getLogger(ExampleTermDaoImpl.class);

    private String TERMS_CSV = "/terms.csv";

    @Override
    public List<Term> getAllTerms() {
        return readFromFile();
    }

    @Override
    public List<Term> getTerms(int from, int count) {
        return CommonUtils.getPartOfList(from, count, readFromFile());
    }

    @Override
    public int countAllTerms() {
        return readFromFile().size();
    }

    public Long generateId() {
        return System.currentTimeMillis();
    }

    @Override
    public boolean createTerm(Term term) {
        return writeToFile(term);
    }

    /**
     * Считываем данные из файла
     *
     * @return
     */
    private List<Term> readFromFile() {
        final List<Term> result = new LinkedList<Term>();
        BufferedReader br = null;

        try {
            final String fullPath = System.getProperty(GlobalConstants.USER_DIR_PROP_NAME) + GlobalConstants.CACHE_DATA + TERMS_CSV;
            final File resourceFile = new File(fullPath);
            if (!resourceFile.exists())
                throw new FileNotFoundException("File " + fullPath + " not found.");

            br = new BufferedReader(new InputStreamReader(
                    new FileInputStream(resourceFile), GlobalConstants.DEFAULT_ENCODING));

            String strLine;
            boolean firstString = true;

            //Read File Line By Line
            while ((strLine = br.readLine()) != null) {
                // пропускаем первую строку, т.к. там лежат имена колонок
                if (firstString) {
                    firstString = false;
                    continue;
                }

                strLine = strLine.replaceAll(GlobalConstants.DOUBLE_QUOTA, GlobalConstants.EMPTY_STRING);

                final String[] fieldArray = strLine.split(GlobalConstants.DOT_COMMA);
                if (fieldArray.length != 5)
                    throw new Exception("Field array more or less than 5 records");

                final Long id = Long.valueOf(fieldArray[0].trim());
                final Long dictId = StringUtils.hasText(fieldArray[1].trim()) ? Long.valueOf(fieldArray[1].trim()) : null;
                final String code = fieldArray[2].trim();
                final String value = fieldArray[3].trim();
                final String description = fieldArray[4].trim();

                // создаем словарь
                final Term term = new Term(id, code, value, description);
                result.add(term);

                // todo ищем родительский словарь
            }
        } catch (IOException e) {
            logger.error("Can't read from file " + TERMS_CSV, e);
        } catch (Exception e) {
            logger.error("Error while read from file " + TERMS_CSV, e);
        } finally {
            if (br != null)
                try {
                    br.close();
                } catch (IOException e) {
                    // ignore
                }
        }

        return result;
    }

    /**
     * Записываем данные в файл
     *
     * @return
     */
    private boolean writeToFile(Term term) {
        BufferedWriter out = null;

        try {
            final String fullPath = System.getProperty(GlobalConstants.USER_DIR_PROP_NAME) + GlobalConstants.CACHE_DATA + TERMS_CSV;
            final File resourceFile = new File(fullPath);
            if (!resourceFile.exists())
                throw new FileNotFoundException("File " + fullPath + " not found.");

            // создаем строку вида: "ID";"DICT";"CODE";"VALUE";"DESCRIPTION"
            final String csvRecord = StringConverter.createCsvRecord(new String[]{term.getId().toString(), term.getDictionary().getId().toString(), term.getCode(), term.getValue(), term.getDescription()});

            out = new BufferedWriter(new OutputStreamWriter(
                    new FileOutputStream(resourceFile, true), GlobalConstants.DEFAULT_ENCODING));

            out.write(csvRecord);
            out.flush();

            return true;
        } catch (IOException e) {
            logger.error("Can't write to file " + TERMS_CSV, e);
        } catch (Exception e) {
            logger.error("Error while write to file " + TERMS_CSV, e);
        } finally {
            if (out != null)
                try {
                    out.close();
                } catch (IOException e) {
                    // ignore
                }
        }
        return false;
    }

}
